package com.thanos.api.storage;

import com.thanos.api.storage.contract.SimpleStorage;
import com.thanos.common.crypto.key.asymmetric.SecureKey;
import com.thanos.web3j.abi.datatypes.Utf8String;
import com.thanos.web3j.crypto.Credentials;
import com.thanos.web3j.protocol.Web3j;
import com.thanos.web3j.model.ThanosTransactionReceipt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 * StorageContractHelper.java description：存储合约辅助类
 *
 * @Author create on 2024-12-19
 */
public class StorageContractHelper {
    
    private static final Logger logger = LoggerFactory.getLogger(StorageContractHelper.class);
    
    /**
     * 部署SimpleStorage合约
     */
    public static String deploy(Web3j web3j, Credentials credentials) throws Exception {
        logger.info("Deploying SimpleStorage contract...");
        
        SimpleStorage contract = SimpleStorage.deploy(
            web3j, 
            credentials, 
            BigInteger.valueOf(1000000000L),
            BigInteger.valueOf(3000000L),
            BigInteger.valueOf(0)
        ).get();
        
        String contractAddress = contract.getContractAddress();
        logger.info("SimpleStorage contract deployed successfully at: {}", contractAddress);
        
        return contractAddress;
    }
    
    /**
     * 设置键值对
     */
    public static ThanosTransactionReceipt setKeyValue(Web3j web3j, String contractAddress, Credentials credentials, String key, String value) throws Exception {
        logger.info("Setting key: {}, value: {} in contract: {}", key, value, contractAddress);
        
        SimpleStorage contract = SimpleStorage.load(
            contractAddress, 
            web3j, 
            credentials, 
            BigInteger.valueOf(1000000000L),
            BigInteger.valueOf(3000000L)
        );
        
        ThanosTransactionReceipt receipt = contract.set(new Utf8String(key), new Utf8String(value)).get();
        logger.info("Set operation completed successfully");
        
        return receipt;
    }
    
    /**
     * 获取键对应的值
     */
    public static String getKeyValue(Web3j web3j, String contractAddress, Credentials credentials, String key) {
        try {
            logger.info("Getting value for key: {} from contract: {}", key, contractAddress);
            
            SimpleStorage contract = SimpleStorage.load(
                contractAddress, 
                web3j, 
                credentials, 
                BigInteger.valueOf(1000000000L),
                BigInteger.valueOf(3000000L)
            );
            
            Utf8String value = contract.get(new Utf8String(key)).get();
            String valueStr = value.getValue();
            logger.info("Retrieved value for key '{}': '{}'", key, valueStr);
            
            return valueStr;
            
        } catch (Exception e) {
            logger.error("Error getting value for key '{}': {}", key, e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 创建多个用户凭证
     */
    public static List<Credentials> createUsers(int count) {
        List<Credentials> users = new ArrayList<>();
        
        // 预定义的私钥用于测试
        String[] privateKeys = {
            "010001308f761b30da0baa33457550420bb8938d040a0c6f0582d9351fd5cead86ff11",
            "020002408f761b30da0baa33457550420bb8938d040a0c6f0582d9351fd5cead86ff22",
            "030003508f761b30da0baa33457550420bb8938d040a0c6f0582d9351fd5cead86ff33",
            "040004608f761b30da0baa33457550420bb8938d040a0c6f0582d9351fd5cead86ff44",
            "050005708f761b30da0baa33457550420bb8938d040a0c6f0582d9351fd5cead86ff55"
        };
        
        for (int i = 0; i < count && i < privateKeys.length; i++) {
            try {
                SecureKey secureKey = SecureKey.fromPrivate(Hex.decode(privateKeys[i]));
                Credentials credentials = Credentials.create(secureKey);
                users.add(credentials);
                logger.info("Created user {} with address: {}", i, credentials.getAddress());
            } catch (Exception e) {
                logger.error("Failed to create user {}: {}", i, e.getMessage(), e);
            }
        }
        
        return users;
    }
}